class DOMObserver {
    constructor() {
        this.observer = null;
        this.callback = null;
    }

    // 开始观察DOM变化
    start(callback) {
        this.callback = callback;
        
        // 创建MutationObserver实例
        this.observer = new MutationObserver(this.handleMutations.bind(this));
        
        // 配置观察选项
        const config = {
            childList: true,     // 观察子节点的添加或删除
            subtree: true,       // 观察所有后代节点
            characterData: true  // 观察文本内容的变化
        };
        
        // 开始观察
        this.observer.observe(document.body, config);
    }

    // 停止观察
    stop() {
        if (this.observer) {
            this.observer.disconnect();
            this.observer = null;
        }
    }

    // 处理DOM变化
    handleMutations(mutations) {
        // 使用防抖函数来避免频繁调用
        const debouncedCallback = debounce(() => {
            if (this.callback) {
                const addedNodes = [];
                
                // 收集所有新增的节点
                mutations.forEach(mutation => {
                    mutation.addedNodes.forEach(node => {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            addedNodes.push(node);
                        }
                    });
                });
                
                // 如果有新增节点，调用回调函数
                if (addedNodes.length > 0) {
                    this.callback(addedNodes);
                }
            }
        }, 500);  // 500ms的防抖时间

        debouncedCallback();
    }

    // 检查节点是否应该被处理
    static shouldProcessNode(node) {
        // 跳过脚本和样式标签
        if (['SCRIPT', 'STYLE', 'NOSCRIPT'].includes(node.tagName)) {
            return false;
        }
        
        // 跳过隐藏元素
        if (node.offsetParent === null) {
            return false;
        }
        
        // 跳过空文本节点
        if (node.nodeType === Node.TEXT_NODE && !node.textContent.trim()) {
            return false;
        }
        
        return true;
    }

    // 获取节点中的所有文本节点
    static getTextNodes(node) {
        const textNodes = [];
        
        if (!this.shouldProcessNode(node)) {
            return textNodes;
        }
        
        const walker = document.createTreeWalker(
            node,
            NodeFilter.SHOW_TEXT,
            {
                acceptNode: function(node) {
                    if (node.textContent.trim()) {
                        return NodeFilter.FILTER_ACCEPT;
                    }
                    return NodeFilter.FILTER_REJECT;
                }
            }
        );
        
        let currentNode;
        while (currentNode = walker.nextNode()) {
            textNodes.push(currentNode);
        }
        
        return textNodes;
    }
}
